package com.hnyyjsxy.web.servlet;

import com.hnyyjsxy.AlipayConfig;
import com.hnyyjsxy.domain.AccountSheet;
import com.hnyyjsxy.domain.Student;
import com.hnyyjsxy.domain.Violate;
import com.hnyyjsxy.service.StudentService;
import com.hnyyjsxy.service.impl.StudentServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;

/**
 * 学生类
 * @date 2021/02/04
 */
@WebServlet("/student_html/stu/*")
public class StudentServlet extends BeanServlet {
    //定义业务层对象
    StudentService studentService = new StudentServiceImpl();

    /**
     * 返回以登录学生的基本信息
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void getStudent(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 从session中取出user数据
        AccountSheet accountSheet = (AccountSheet) request.getSession().getAttribute("user");
        //2. 调用service层获取学生实体类对象
        Student student = studentService.getStudentBySid(accountSheet.getAccount());
        //3. 将student转json并传给前端
        if (student != null){
            respondOnly(student,response);
        }
    }

    /**
     * 学生退出登录
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void exit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 销毁session,这个方法就是session自己将自己弄死
        //使此会话无效，然后取消对任何绑定到它的对象的绑定。
        request.getSession().invalidate();
        //2. 重定向至登录界面
        response.sendRedirect(request.getContextPath()+"/index.html");
    }

    /**
     * 学生违纪情况
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void breakTheRule (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 从session中取出user数据
        AccountSheet accountSheet = (AccountSheet) request.getSession().getAttribute("user");
        //2. 取出学号
        String sid = accountSheet.getAccount();
        //3. 将该学生的学号传给业务层
        List<Violate> list = studentService.queryDeregulation(sid);
        //4. 转json响应前端
        respondOnly(list,response);
    }

    /**
     * 学生提交调换宿舍的申请
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void swap (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 获取请求参数
        String room = request.getParameter("newRoom");
        String bed = request.getParameter("newBed");
        //2. 根据学号查询数据库，得到学生信息
        AccountSheet accountSheet = (AccountSheet) request.getSession().getAttribute("user");
        Student student = studentService.getStudentBySid(accountSheet.getAccount());
        //3. 将学生实体类对象 和 请求参数传给业务层
        studentService.studentApply(student,room,bed);
    }

    /**
     * 学生字符电费的实现
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void pay (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String charge = request.getParameter("charge");
        if (charge != null && (!("".equals(charge)))){
            double money = Double.parseDouble(charge);
            //1. 从session中取出user数据
            AccountSheet accountSheet = (AccountSheet) request.getSession().getAttribute("user");
            //2. 调用service层获取学生实体类对象
            Student student = studentService.getStudentBySid(accountSheet.getAccount());
            //3. 将当前学生信息 以及新增的电费传递给service层并改变数据库中的数据
            studentService.alterCharge(student,money);


            //接下来开始操作--------------------------------------------------------
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

            //设置请求参数
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            // 设置同步通知url
            alipayRequest.setReturnUrl(AlipayConfig.return_url);
            // 设置异步通知url
            alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

            // 组装订单详情信息
            AlipayTradePagePayModel payModel = new AlipayTradePagePayModel();

            payModel.setOutTradeNo(System.currentTimeMillis() + ""); // 商品订单号
            payModel.setSubject("宿舍电费");// 商品名称
            payModel.setTotalAmount(money + "");// 订单金额

            // 还有一个必填项 销售产品码，与支付宝签约的产品码名称
            payModel.setProductCode("FAST_INSTANT_TRADE_PAY");

            //把拼装号的支付订单model存进支付请求中
            alipayRequest.setBizModel(payModel);
            //请求
            String result = null;
            try {
                // 调用SDK生成表单
                result = alipayClient.pageExecute(alipayRequest).getBody();
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            //输出  往页面上生成表单信息  阿里提供的页面信息
            //out.println(result);
            request.getSession().setAttribute("result", result);
            response.sendRedirect(request.getContextPath() + "/student_html/pay.jsp");
        }

    }


    // 提炼获取支付宝发送的反馈信息
    private Map<String, String> getParameterMap(Map<String, String[]> requestParams) {
        Map<String, String> params = new HashMap<String, String>();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }

    // 封装异步请求
    //判断验签就是付钱是否成功吗，成功就跳转到订单页面，没成功就返回fail
    public void asyncNotify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Map<String, String> params = getParameterMap(request.getParameterMap());
        System.out.println("===================异步通知反馈的结果：" + params);
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        System.out.println("--------异步通知验证结果：" + signVerified);
        if (!signVerified) {
            // 说明验签失败了
        } else {
            //调用service 改变订单支付状态
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        }
    }

    /**
     * 封装同步通知 可以自定义跳转的资源路径
     */
    public void syncNotify(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //支付成功，发送邮箱告知学生支付成功，当前余额
//        AccountSheet accountSheet = (AccountSheet) request.getSession().getAttribute("user");
//        Student student = studentService.getStudentBySid(accountSheet.getAccount());
//        studentService.inform(student);
        //重定向至主界面
        response.sendRedirect(request.getContextPath() + "/student_html/stu_main_page.html");
    }

}
